﻿using Share;
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;



public static class StringTools
{



    /// <summary>
    /// 数字转字符串，Lua的数字转字符串会保留小数点后面的0，C#的不会。
    /// </summary>
    /// <param name="num">数字。</param>
    /// <param name="w">固定最小宽度。</param>
    /// <returns>字符串。</returns>
    public static string NumberToString(double num, int w = 0)
    {
        string str = num.ToString();
        if (str.Length >= w)
        {
            return str;
        }
        return new string(' ', w - str.Length) + str;
    }
    /// <summary>
    /// long转string
    /// </summary>
    /// <param name="str">输入字符串</param>
    /// <param name="valueDefault">如果没有数字，返回的默认值</param>
    /// <returns></returns>
    public static long StringToLong(string str, long valueDefault = -1)
    {
        long value;
        if (!long.TryParse(str, out value))
            return valueDefault;
        if (value < long.MinValue || value > long.MaxValue)
            return valueDefault;
        return value;
    }

    /// <summary>
    /// 将字符串以 特定字符 为间隔分解成字符串列表
    /// </summary>
    /// <param name="strParam">输入字符串</param>
    /// <param name="splitParam">间隔的字符</param>
    /// <returns></returns>
    public static List<string> GetStringList(string strParam, char splitParam = ',')
    {
        List<string> strList = new List<string>();
        if (string.IsNullOrEmpty(strParam))
            return strList;
        string[] nodeNames = strParam.Split(splitParam);
        foreach (var idStr in nodeNames)
        {
            string str = idStr.Trim();
            if (string.IsNullOrEmpty(str))
                continue;
            strList.Add(str);
        }
        return strList;
    }
    //  读取csv格式的字符串
    public static List<string> GetStringListWithSpace(string strParam, char splitParam = ',')
    {

        List<string> strList = new List<string>();
        if (string.IsNullOrEmpty(strParam))
            return strList;

        string strKey = ",\"";  // 字符串开始
        string strKey2 = "\","; // 字符串结束
        if (strParam.IndexOf(strKey) > 0) // 如果有 引号，就要走引号处理流程
        {
            int nLast = 0;
            int index = strParam.IndexOf(",");
            while (index <= strParam.Length && index > 0)
            {
                var key = strParam.Substring(nLast, index - nLast);
                key = key.Replace("\"", "");
                strList.Add(key);
                // 如果下一个字符是引号，就找下一个引号s
                if (index < strParam.Length - 1 && strParam[index + 1] == '\"')
                {
                    nLast = index + 1;
                    index = strParam.IndexOf(strKey2, nLast) + 1; // 这里一定会找到
                }
                else
                {
                    nLast = index + 1;
                    index = strParam.IndexOf(",", nLast);
                }
            }

        }
        else
        {
            string[] nodes = strParam.Split(splitParam);
            strList = new List<string>(nodes);
        }

        return strList;
    }
    // 处理带小数的字符串
    /// <summary>
    /// 将字符串转换为浮点列表，以逗号间隔
    /// </summary>
    /// <param name="strParam"></param>
    /// <returns></returns>
    /// <summary>
    /// 将字符串转换为指定类型的列表
    /// </summary>
    /// <typeparam name="T">目标类型</typeparam>
    /// <param name="strParam">输入字符串</param>
    /// <param name="splitParam">分隔符</param>
    /// <returns>转换后的列表</returns>
    public static List<T> GetList<T>(string strParam, char splitParam = ',') where T : IConvertible
    {
        if (string.IsNullOrEmpty(strParam))
            return new List<T>();

        RemoveBrackets(ref strParam);
        string[] nodeNames = SplitString(strParam, splitParam);
        var result = new List<T>(nodeNames.Length);

        foreach (var idStr in nodeNames)
        {
            if (string.IsNullOrEmpty(idStr))
                continue;

            try
            {
                result.Add((T)Convert.ChangeType(idStr, typeof(T)));
            }
            catch (Exception ex)
            {
                XKLog.LogWarning($"Failed to parse {idStr} to {typeof(T).Name}: {ex.Message}");
            }
        }

        return result;
    }

    //根据,将字符串转为字符串数组
    public static string[] SplitString(string str, char splitParam = ',')
    {
        return str.Split(splitParam);
    }
    // 去掉字符串里的 [ ] 符号
    public static void RemoveBrackets(ref string strParam)
    {
        strParam = strParam.Replace("[", "");
        strParam = strParam.Replace("]", "");
    }

    /// <summary>
    /// 将整数数组转换为字符串
    /// </summary>
    /// <param name="list">整数数组</param>
    /// <param name="num">要转换的元素数量，-1表示全部</param>
    /// <returns>转换后的字符串</returns>
    public static string ListToString(int[] list, int num = -1)
    {
        if (list == null || list.Length == 0)
            return string.Empty;

        if (num < 0 || num > list.Length)
            num = list.Length;

        var sb = new StringBuilder(num * 6); // 预分配空间
        for (int i = 0; i < num; i++)
        {
            sb.Append(list[i]);
            if (i < num - 1)
                sb.Append(',');
        }
        return sb.ToString();
    }

    /// <summary>
    ///  获取字符串里小数点后的数字   0.1123 =>  1123
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static int GetIntFromString(string str)
    {
        var index = str.IndexOf(".");
        if (index > 0)
            str = str.Substring(0, index);
        else if (index == 0)
            str = "0";
        return int.Parse(str);
    }
    /// <summary>
    /// 获取字符串里 指定 strKey = 的数值
    /// 支持以 | 为间隔的多组字符对应
    /// </summary>
    /// <param name="str"></param>
    /// <param name="strKey"></param>
    /// <param name="def"></param>
    /// <returns></returns>
    static string GetValueFromString(string str, string strKey, string def = "")
    {
        if (String.IsNullOrEmpty(str))
            return def;
        if (str == "-1")
            return def;
        string[] nodeNames = str.Split('|');
        string[] data = nodeNames[0].Split('=');
        for (int i = 0; i < nodeNames.Length; ++i)
        {
            data = nodeNames[i].Split('=');
            if (data.Length == 2)
            {
                if (data[0] == strKey) // 过滤掉type
                    return data[1];
            }
        }
        return def;
    }
    /// <summary>
    /// 获取字符串字典的int值
    /// </summary>
    /// <param name="str"></param>
    /// <param name="strKey"></param>
    /// <param name="def">默认值</param>
    /// <returns></returns>
    public static int GetIntFromString(string str, string strKey, int def = 0)
    {
        string value = GetValueFromString(str, strKey, def.ToString());
        return int.Parse(value);
    }
    /// <summary>
    /// 获取字符串字典的float值
    /// </summary>
    /// <param name="str"></param>
    /// <param name="strKey"></param>
    /// <param name="fDefault"></param>
    /// <returns></returns>
    public static float GetFloatFromString(string str, string strKey, float fDefault = 0)
    {
        string value = GetValueFromString(str, strKey, fDefault.ToString());
        return float.Parse(value);

    }
    ///// <summary>
    ///// 获取字符串字典的int列表    
    ///// </summary>
    ///// <param name="str"></param>
    ///// <param name="idList"></param>
    public static void GetIntListFromString(string str, List<int> idList)
    {
        if (string.IsNullOrEmpty(str))
            return;
        if (str == "-1")
            return;
        string[] nodeNames = str.Split('|');
        int type = 0;
        string[] data = nodeNames[0].Split('=');
        for (int i = 0; i < nodeNames.Length; ++i)
        {
            data = nodeNames[i].Split('=');
            if (data.Length == 2)
            {
                if (int.TryParse(data[0], out type)) // 如果类型是数字
                    idList.Add(int.Parse(data[1]));
            }
        }
    }

    /// <summary>
    ///  将字符串转换为long列表，以逗号间隔
    /// </summary>
    /// <param name="strParam"></param>
    /// <returns></returns>
    public static List<long> GetLongList(string strParam, char splitParam = ',')
    {
        List<long> idList = StringToList<long>(strParam);
        return idList;
    }

    public static List<int> GetIntList(string strParam, char splitParam = ',')
    {
        // Create a new list of integers
        List<int> idList = StringToList<int>(strParam);
        // Return the list of integers
        return idList;
    }

    public static List<T> StringToList<T>(string str, char splitParam = ',')
    {
        List<T> list = new List<T>();
        string[] value = SplitString(str, splitParam);
        for (int i = 0; i < value.Length; i++)
        {
            list.Add((T)Convert.ChangeType(value[i], typeof(T)));
        }
        return list;
    }
    public static void GetLongListFromString(string str, List<long> idList)
    {
        if (str == null)
            return;
        if (str == "")
            return;
        if (str == "-1")
            return;
        string[] nodeNames = str.Split('|');

        string[] data = nodeNames[0].Split('=');
        for (int i = 0; i < nodeNames.Length; ++i)
        {
            data = nodeNames[i].Split('=');
            if (data.Length == 2)
            {
                if (System.Text.RegularExpressions.Regex.IsMatch(data[0], @"^\d{1}$")) // 如果类型是数字
                    idList.Add(long.Parse(data[1]));
            }
        }
    }
    public static List<string> GetStringListCheckNull(string strParam, char splitParam = ',')
    {
        if (string.IsNullOrEmpty(strParam))
            return null;
        return GetStringList(strParam, splitParam);
    }

    public static Dictionary<int, int> TranslateStringToIntDic(string str)
    {
        Dictionary<int, int> strDic = new Dictionary<int, int>();
        string[] nodeNames = str.Split('|');
        for (int i = 0; i < nodeNames.Length; ++i)
        {
            string[] data = nodeNames[i].Split('=');
            if (data.Length == 2)
                strDic.Add(int.Parse(data[0]), int.Parse(data[1]));
        }
        return strDic;
    }

    public static Dictionary<string, string> TranslateStringToDic(string str)
    {
        Dictionary<string, string> strDic = new Dictionary<string, string>();
        string[] nodeNames = str.Split('|');
        for (int i = 0; i < nodeNames.Length; ++i)
        {
            string[] data = nodeNames[i].Split('=');
            if (data.Length == 2)
                strDic.Add(data[0], data[1]);
        }
        return strDic;
    }
    /// <summary>
    /// 字符串生成字符串字典
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    static public int InitSmartDic(ref Dictionary<string, string> dic, string strParam)
    {

        string strDic = "";
        try
        {
            if (strParam != "")
            {
                string[] nodeNames = strParam.Split('|');
                for (int i = 0; i < nodeNames.Length; ++i)
                {
                    if (nodeNames[i] == "")
                        continue;
                    string[] data = nodeNames[i].Split('=');
                    if (data.Length != 2)
                    {
                        XKLog.LogError($"[ {strParam} + 第 {i + 1} 个参数格式不对");
                    }
                    else
                    {
                        strDic = data[0];
                        dic.Add(data[0], data[1]);
                    }
                }
            }
        }
        catch (ArgumentException e)
        {
            XKLog.LogError($"{strDic}  重复了      {e.Message}");
        }
        return -1;
    }


    /// <summary>
    /// 字符串以|分割转换成int列表
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static List<int> TranslateStringToIntList(string str)
    {
        List<int> data = new List<int>();
        if (str == null)
            return null;
        if (str == "")
            return null;
        string[] temp = str.Split('|');
        for (int i = 0; i < temp.Length; ++i)
        {
            data.Add(int.Parse(temp[i]));
            //Debug.Log(data[i]);
        }
        return data;
    }

    public static string ChangeNonBreakingSpaceText(string str)
    {
        if (string.IsNullOrEmpty(str))
            return "";
        string no_breaking_space = "\u00A0";
        if (str.Contains(" "))
            return str.Replace(" ", no_breaking_space);
        return str;
    }

    public static string SearchString(string s, string s1, string s2)
    {
        int n1, n2;
        n1 = s.IndexOf(s1, 0);
        if (n1 < 0)
        {
            return "";
        }
        n1 = n1 + s1.Length;
        n2 = s.IndexOf(s2, n1);
        return s.Substring(n1, n2 - n1);
    }
    // 浮点值按des保留有效数字
    // 这里先把小数保留位数计算好，转换成字符串，然后转换成浮点，会自动去掉无效的0，在转换成字符串，就成了指定位数的额有效数字
    public static string GetFloatDecimalString(float fValue, int dec)
    {
        string str = "#0.";
        for (int i = 0; i < dec; ++i)
            str += "0";
        return float.Parse(fValue.ToString(str)).ToString();
    }

    public static string StringFormatWithStrParam(string msg, string strParam)
    {
        string[] args = strParam.Split(',');
        string[] b = msg.Split('{');
        if (b.Length - 1 == args.Length)
            return string.Format(msg, args);
        return msg;
    }


    public static string NormalizeString(string str)
    {
        char space = (char)160;
        char newSpace = (char)32;
        return str.Replace(space, newSpace);
    }

    public static List<string> CreateStringList()
    {
        List<string> strList = new List<string>();

        return strList;
    }

    public static string ToMoneyNum(float num)
    {
        if (num > 9999)
        {
            return Mathf.Floor(num / 1000.0f) + "K";
        }
        return num.ToString();
    }
    /// <summary>
    /// int列表转换成Vector3
    /// </summary>
    /// <param name="pos"></param>
    /// <returns></returns>
    public static bool IntList2Vector(List<int> list, ref Vector3 pos)
    {
        // 这是二维
        if (list.Count >= 2)
        {
            pos.x = list[0];
            pos.y = list[1];
            if (list.Count == 3)
            {
                pos.z = list[2];
            }
        }
        else
        {
            return false;
        }
        return true;
    }


    /// <summary>
    /// 生成随机字符串
    /// </summary>
    /// <param name="length">字符串长度</param>
    /// <param name="useNumbers">是否包含数字</param>
    /// <param name="useSpecialChars">是否包含特殊字符</param>
    /// <returns>随机字符串</returns>
    public static string GenerateRandomString(int length, bool useNumbers = true, bool useSpecialChars = false)
    {
        const string letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        const string numbers = "0123456789";
        const string specialChars = "!@#$%^&*()_+-=";

        var chars = new StringBuilder(letters);
        if (useNumbers) chars.Append(numbers);
        if (useSpecialChars) chars.Append(specialChars);

        var random = new System.Random();
        var result = new StringBuilder(length);

        for (int i = 0; i < length; i++)
        {
            result.Append(chars[random.Next(chars.Length)]);
        }

        return result.ToString();
    }

    public static string GetAssetPathFromFullPath(string fullPath)
    {
        int index = fullPath.IndexOf("Assets");
        return fullPath.Substring(index);
    }

    /// <summary>
    /// 简单字符串加密
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <param name="key">加密密钥</param>
    /// <returns>加密后的字符串</returns>
    public static string EncryptString(string input, string key)
    {
        if (string.IsNullOrEmpty(input)) return input;

        var inputBytes = Encoding.UTF8.GetBytes(input);
        var keyBytes = Encoding.UTF8.GetBytes(key);
        var result = new byte[inputBytes.Length];

        for (int i = 0; i < inputBytes.Length; i++)
        {
            result[i] = (byte)(inputBytes[i] ^ keyBytes[i % keyBytes.Length]);
        }

        return Convert.ToBase64String(result);
    }

    /// <summary>
    /// 简单字符串解密
    /// </summary>
    /// <param name="input">加密字符串</param>
    /// <param name="key">解密密钥</param>
    /// <returns>解密后的字符串</returns>
    public static string DecryptString(string input, string key)
    {
        if (string.IsNullOrEmpty(input)) return input;

        var inputBytes = Convert.FromBase64String(input);
        var keyBytes = Encoding.UTF8.GetBytes(key);
        var result = new byte[inputBytes.Length];

        for (int i = 0; i < inputBytes.Length; i++)
        {
            result[i] = (byte)(inputBytes[i] ^ keyBytes[i % keyBytes.Length]);
        }

        return Encoding.UTF8.GetString(result);
    }

    /// <summary>
    /// 计算字符串的MD5哈希值
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <returns>32位MD5哈希值</returns>
    public static string CalculateMD5Hash(string input)
    {
        if (string.IsNullOrEmpty(input)) return string.Empty;

        using (var md5 = System.Security.Cryptography.MD5.Create())
        {
            var inputBytes = Encoding.UTF8.GetBytes(input);
            var hashBytes = md5.ComputeHash(inputBytes);

            var sb = new StringBuilder();
            foreach (var b in hashBytes)
            {
                sb.Append(b.ToString("x2"));
            }
            return sb.ToString();
        }
    }

    /// <summary>
    /// 格式化字符串为指定长度
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <param name="length">目标长度</param>
    /// <param name="paddingChar">填充字符</param>
    /// <param name="alignLeft">是否左对齐</param>
    /// <returns>格式化后的字符串</returns>
    public static string FormatStringLength(string input, int length, char paddingChar = ' ', bool alignLeft = true)
    {
        if (input == null) input = string.Empty;

        if (input.Length > length)
            return input.Substring(0, length);

        if (alignLeft)
            return input.PadRight(length, paddingChar);
        else
            return input.PadLeft(length, paddingChar);
    }

    /// <summary>
    /// 安全截取字符串
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <param name="startIndex">开始索引</param>
    /// <param name="length">截取长度</param>
    /// <returns>截取后的字符串</returns>
    public static string SafeSubstring(string input, int startIndex, int length)
    {
        if (string.IsNullOrEmpty(input)) return string.Empty;

        if (startIndex < 0) startIndex = 0;
        if (length < 0) length = 0;

        if (startIndex >= input.Length) return string.Empty;

        if (startIndex + length > input.Length)
            length = input.Length - startIndex;

        return input.Substring(startIndex, length);
    }

    /// <summary>
    /// 反转字符串
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <returns>反转后的字符串</returns>
    public static string ReverseString(string input)
    {
        if (string.IsNullOrEmpty(input)) return input;

        char[] charArray = input.ToCharArray();
        Array.Reverse(charArray);
        return new string(charArray);
    }

    /// <summary>
    /// 统计字符串中指定字符出现的次数
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <param name="target">目标字符</param>
    /// <returns>出现次数</returns>
    public static int CountCharOccurrences(string input, char target)
    {
        if (string.IsNullOrEmpty(input)) return 0;

        int count = 0;
        foreach (char c in input)
        {
            if (c == target) count++;
        }
        return count;
    }

    /// <summary>
    /// 统计字符串中指定子字符串出现的次数
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <param name="target">目标子字符串</param>
    /// <returns>出现次数</returns>
    public static int CountSubstringOccurrences(string input, string target)
    {
        if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(target)) return 0;

        int count = 0;
        int index = 0;

        while ((index = input.IndexOf(target, index)) != -1)
        {
            count++;
            index += target.Length;
        }

        return count;
    }

    /// <summary>
    /// 比较两个字符串（忽略大小写）
    /// </summary>
    /// <param name="str1">字符串1</param>
    /// <param name="str2">字符串2</param>
    /// <returns>是否相等</returns>
    public static bool CompareIgnoreCase(string str1, string str2)
    {
        if (str1 == null && str2 == null) return true;
        if (str1 == null || str2 == null) return false;
        return str1.Equals(str2, StringComparison.OrdinalIgnoreCase);
    }

    /// <summary>
    /// 去除字符串中的重复子字符串
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <param name="separator">分隔符</param>
    /// <returns>去重后的字符串</returns>
    public static string RemoveDuplicateSubstrings(string input, char separator)
    {
        if (string.IsNullOrEmpty(input)) return input;

        var parts = input.Split(separator);
        var uniqueParts = new HashSet<string>(parts);
        return string.Join(separator.ToString(), uniqueParts);
    }

    /// <summary>
    /// 将字符串按指定长度分割
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <param name="chunkSize">每段长度</param>
    /// <returns>分割后的字符串数组</returns>
    public static string[] SplitByLength(string input, int chunkSize)
    {
        if (string.IsNullOrEmpty(input) || chunkSize <= 0)
            return new string[0];

        int length = input.Length;
        int chunks = (int)Math.Ceiling(length / (double)chunkSize);
        var result = new string[chunks];

        for (int i = 0; i < chunks; i++)
        {
            int startIndex = i * chunkSize;
            int takeLength = Math.Min(chunkSize, length - startIndex);
            result[i] = input.Substring(startIndex, takeLength);
        }

        return result;
    }

    /// <summary>
    /// 将字符串数组合并为单个字符串
    /// </summary>
    /// <param name="parts">字符串数组</param>
    /// <param name="separator">分隔符</param>
    /// <returns>合并后的字符串</returns>
    public static string JoinStrings(string[] parts, string separator = "")
    {
        if (parts == null || parts.Length == 0)
            return string.Empty;

        var sb = new StringBuilder();
        for (int i = 0; i < parts.Length; i++)
        {
            if (i > 0 && !string.IsNullOrEmpty(separator))
                sb.Append(separator);
            sb.Append(parts[i]);
        }
        return sb.ToString();
    }

    /// <summary>
    /// 用指定字符填充字符串到指定长度
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <param name="totalWidth">总长度</param>
    /// <param name="paddingChar">填充字符</param>
    /// <param name="alignLeft">是否左对齐</param>
    /// <returns>填充后的字符串</returns>
    public static string PadString(string input, int totalWidth, char paddingChar = ' ', bool alignLeft = true)
    {
        if (input == null) input = string.Empty;

        if (input.Length >= totalWidth)
            return input;

        if (alignLeft)
            return input.PadRight(totalWidth, paddingChar);
        else
            return input.PadLeft(totalWidth, paddingChar);
    }

    /// <summary>
    /// 转义字符串中的特殊字符
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <returns>转义后的字符串</returns>
    public static string EscapeString(string input)
    {
        if (string.IsNullOrEmpty(input)) return input;

        var sb = new StringBuilder();
        foreach (char c in input)
        {
            switch (c)
            {
                case '\"': sb.Append("\\\""); break;
                case '\\': sb.Append("\\\\"); break;
                case '\0': sb.Append("\\0"); break;
                case '\a': sb.Append("\\a"); break;
                case '\b': sb.Append("\\b"); break;
                case '\f': sb.Append("\\f"); break;
                case '\n': sb.Append("\\n"); break;
                case '\r': sb.Append("\\r"); break;
                case '\t': sb.Append("\\t"); break;
                case '\v': sb.Append("\\v"); break;
                default: sb.Append(c); break;
            }
        }
        return sb.ToString();
    }


    /// <summary>
    /// 将字符串转换为全大写
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <returns>全大写字符串</returns>
    public static string ToUpper(string input)
    {
        if (string.IsNullOrEmpty(input)) return input;
        return input.ToUpper();
    }

    /// <summary>
    /// 将字符串转换为全小写
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <returns>全小写字符串</returns>
    public static string ToLower(string input)
    {
        if (string.IsNullOrEmpty(input)) return input;
        return input.ToLower();
    }

    /// <summary>
    /// 将字符串转换为指定编码
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <param name="encoding">目标编码</param>
    /// <returns>编码后的字节数组</returns>
    public static byte[] ConvertEncoding(string input, Encoding encoding)
    {
        if (string.IsNullOrEmpty(input)) return new byte[0];
        return encoding.GetBytes(input);
    }

}
